package com.pine.dbant.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pine.dbant.common.model.JdbcMetadataTreeView;
import com.pine.dbant.common.plugin.meta.DefaultMetadataNode;
import com.pine.dbant.common.plugin.meta.MetadataNode;
import com.pine.dbant.core.entity.Connection;
import com.pine.dbant.core.entity.Relation;
import com.pine.dbant.core.mapper.ConnectionMapper;
import com.pine.dbant.core.model.ConnState;
import com.pine.dbant.core.model.RelationType;
import com.pine.dbant.core.model.dto.ConnectionDTO;
import com.pine.dbant.core.model.vo.ConnectionVO;
import com.pine.dbant.core.service.ConnectionService;
import com.pine.dbant.core.service.RelationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

@Service
public class ConnectionServiceImpl implements ConnectionService {

    @Autowired
    private ConnectionMapper connectionMapper;
    @Autowired
    private RelationService relationService;


    @Override
    public List<MetadataNode> getTree() {
        return connectionMapper.selectList(new LambdaQueryWrapper<Connection>().eq(Connection::getState, ConnState.RUNNING))
                .stream().map(connection -> new DefaultMetadataNode().setName(connection.getConnName())
                        .setId(String.valueOf(connection.getId()))
                        .setType(JdbcMetadataTreeView.CONN.getType())
                        .addProperty("ip", connection.getHost())
                        .addProperty("connId", connection.getId())
                        .addProperty("pluginId", connection.getDsType().toLowerCase(Locale.ROOT))).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(ConnectionDTO connectionDTO) {
        Connection connection = new Connection();
        BeanUtils.copyProperties(connectionDTO, connection);
        connectionMapper.insert(connection);
        if (connectionDTO.getDirId() != null) {
            Relation relation = new Relation();
            relation.setResId(connectionDTO.getDirId());
            relation.setTargetId(connection.getId());
            relation.setType(RelationType.DIR_CONNECTION.name());
            this.relationService.save(relation);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(ConnectionDTO connectionDTO) {
        Connection connection = new Connection();
        BeanUtils.copyProperties(connectionDTO, connection);
        connectionMapper.updateById(connection);
        if (connectionDTO.getDirId() != null) {
            this.relationService.deleteByTargetId(connection.getId(), RelationType.DIR_CONNECTION);
            Relation relation = new Relation();
            relation.setResId(connectionDTO.getDirId());
            relation.setTargetId(connection.getId());
            relation.setType(RelationType.DIR_CONNECTION.name());
            this.relationService.save(relation);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long connId) {
        this.connectionMapper.deleteById(connId);
        this.relationService.deleteByTargetId(connId, RelationType.DIR_CONNECTION);
    }

    @Override
    public void copy(Long connId, Long dirId) {

    }

    @Override
    public ConnectionVO getVOById(Long connId) {
        return null;
    }

    @Override
    public Connection getById(Long connId) {
        return this.connectionMapper.selectById(connId);
    }

    @Override
    public List<ConnectionVO> list() {
        return this.connectionMapper.selectVOList();
    }
}
